define(['config', 'yago', 'ynet'], function(config, Yago, N){
    
    var a4n;
    
    var ttAName = Yago.transitionAttrName;
    var tfAName = Yago.transformAttrName;
    
    function mkdiv(className){
        var d = document.createElement('div');
        d.className = className;
        return d;
    }
    
    var Channel = {
        
        ready : function(a){
            
            a4n = a;
        },
        
        init : function(d){
            var sc = mkdiv('apf-channel-scroll');
            var dp = mkdiv('apf-channel-dropbtn');
            var fd = mkdiv('apf-channel-foldbtn');
            var ct = mkdiv('apf-channel-scroll-content');
            var ud = mkdiv('apf-channel-scroll-under');
            
            var sortLayer      = mkdiv('apf-channel-sl');
            var sortLayerUp    = mkdiv('apf-channel-sl-u');
            var sortLayerDown  = mkdiv('apf-channel-sl-d');
            var sortLayerLabel = mkdiv('apf-channel-sl-l');
            
                    
            var localData = {};
            
            var h_sort_layer,
                h1, h2;
            
            d.appendChild(sortLayer);
            sortLayer.appendChild(fd);
            sortLayer.appendChild(sortLayerUp);
            sortLayer.appendChild(sortLayerDown);
            sortLayer.appendChild(sortLayerLabel);
            h_sort_layer = parseInt(
                    (Yago.scrH - 
                        config.SIZE.CHANNEL_HEIGHT_ALL -
                        config.SIZE.HEAD_HEIGHT -
                        config.SIZE.CHANNEL_SORT_LABEL_HEIGHT
                    ) / 2);
            h2 = h_sort_layer + config.SIZE.CHANNEL_HEIGHT_ALL;
            sortLayer.style.width      = Yago.scrW + 'px';
            sortLayer.style.height     = Yago.scrH - config.SIZE.HEAD_HEIGHT + 'px';
            sortLayerUp.style.top      = config.SIZE.CHANNEL_HEIGHT_ALL + 'px';
            sortLayerDown.style.bottom = '0px';
            sortLayerDown.style.height = h_sort_layer + 'px';
            sortLayerUp.style.height   = h_sort_layer + 'px';
            sortLayerLabel.style.top   = h2 + 'px';
            sortLayerLabel.style.height     = 
            sortLayerLabel.style.lineHeight = 
                config.SIZE.CHANNEL_SORT_LABEL_HEIGHT + 'px';
            
            
            Yago.touch.tap(dp, 0, function(){
                d.refreshSortPanel();
                sortLayer.style[tfAName] = 'translateY(-100%) scale(1,0)';
                sortLayer.style.display  = 'block';
                sortLayer.style.opacity  = '0';
                sortLayer.style[ttAName] = 'all ease-out 300ms';
                setTimeout(function(){
                   sortLayer.style[tfAName] = 'translateY(0) scale(1,1)'; 
                    sortLayer.style.opacity = '1';
                }, 10);
            });
            Yago.touch.tap(fd, 0, function(){
                if(moved){
                    d.setDisplayedChannels(sorted_u.splice(0));
                }
                sortLayer.style[tfAName] = 'translateY(-100%) scale(1,0)';
                sortLayer.style.opacity  = '0';
                sortLayer.style[ttAName] = 'all ease-out 300ms';
                setTimeout(function(){
                    sortLayer.style[ttAName] = '';
                    sortLayer.style.display  = 'none';
                }, 350);
            });
            
            sortLayerLabel.innerHTML = config.TEXT.CHANNEL_SORT_LABEL;
            d.appendChild(sc);
            d.appendChild(dp);
            sc.appendChild(ct);
            // 频道选择栏应用轮播手势
            Yago.touch.enableScroll(ct, 'x', {
                preventDefault: true
            });
            // 点击选择频道
            Yago.touch.tap(ct, 0, function(e){
                d.switchToChannel(this.dataset.channel);
            }, 'apf-channel-scroll-item');
            
            var sortItemToDrag = mkdiv('apf-channel-sl-td');
            sortLayer.appendChild(sortItemToDrag);
            sortItemToDrag.style.display = 'none';
            
            var sorted_u = [];
            var sorted_d = [];
            var sorting = null;
            
            d.apfIndex   = 0;       //当前频道序号
            d.apfChannel = null;    //当前频道
            d.channels   = {};
            
            d.apfFocusTo = function(c){
                var dst  = d.channels[c].navi;
                var rect = dst.getBoundingClientRect();
                ud.style.left = - ct.mv.offset + rect.left + config.SIZE.CHANNEL_LEFT + 'px';
                if(d.apfChannel){
                    d.channels[d.apfChannel].navi.className = 'apf-channel-scroll-item';
                }
                d.apfIndex   = dst.dataset.index;
                d.apfChannel = c;
                d.channels[c].navi.className = 'apf-channel-scroll-item cur';
            }
            
            d.setChannels = function(c){
                var i;
                for(i in c){
                    d.channels[i] = {
                        key : i,
                        text : c[i],
                        item : null,
                        navi : null
                    };
                }
            }
            
            d.setDisplayedChannels = function(c){
                var i, e, ad = [];
                ct.innerHTML = '';
                ct.appendChild(ud);
                sorted_u.length = 0;
                for(i = 0; i < c.length; i ++){
                    e = mkdiv('apf-channel-scroll-item');
                    e.innerHTML = d.channels[c[i]].text;
                    e.dataset.channel = c[i];
                    e.dataset.index   = sorted_u.length;
                    ct.appendChild(e);
                    d.channels[c[i]].navi = e;
                    sorted_u.push(c[i]);
                }
                for(i in d.channels){
                    if(sorted_d.indexOf(i) < 0 && c.indexOf(i) < 0){
                        sorted_d.push(i);
                    }
                }
                ct.mv.reWrap();
                d.switchToChannel(c[0]);
            }
            
            d.switchToChannel = function(c){
                if(d.apfChannel && localData[d.apfChannel] && d.apfLinkList){
                    localData[d.apfChannel].offset = d.apfLinkList.apfContent.mv.offset;
                }
                if(localData[c]){
                    slideAnimation(c, false);
                    setTimeout(function(){
                        d.apfLinkList && d.apfLinkList.apfUpdateContent(localData[c].data, localData[c].offset);
                    }, 350);
                }else{
                    slideAnimation(c, true);
                    setTimeout(function(){
                        d.refreshChannel(c);
                    }, 350);
                }
                d.apfFocusTo(c);
            }
            function slideAnimation(c, needRefresh){
                var index = d.channels[c].navi.dataset.index;
                if(d.apfLinkList){
                    if(index > d.apfIndex){
                        d.apfLinkList.apfSlideToRight(needRefresh);
                    }else if(index < d.apfIndex){
                        d.apfLinkList.apfSlideToLeft(needRefresh);
                    }
                }
            }
            
            var item_width, item_height;
            
            function resort(){
                var w   = config.SIZE.CHANNEL_SORT_ITEM_WIDTH;
                var h   = config.SIZE.CHANNEL_SORT_ITEM_HEIGHT;
                var ipl = config.SIZE.CHANNEL_SORT_ITEM_PER_LINE;
                var mg  = Math.floor((Yago.scrW - ipl * w) / 8);
                item_width  = w + mg * 2;
                item_height = h;
                resort_sub(sorted_u);
                resort_sub(sorted_d);
                function resort_sub(to_sort){
                    var i, e;
                    for(i = 0; i < to_sort.length; i ++){
                        if(to_sort[i].length == 0){
                            continue;
                        }
                        e = d.channels[to_sort[i]].item;
                        e.apfC = (i % ipl);
                        e.apfR = Math.floor(i / ipl);
                        e.apfX = e.apfC * (w + mg * 2) + mg;
                        e.apfY = e.apfR * h;
                        e.style[tfAName] = 'translate('+e.apfX+'px,'+e.apfY+'px)';
                    }
                }
            }
            
            d.refreshSortPanel = function(){
                sortLayerDown.innerHTML = '';
                sortLayerUp.innerHTML = '';
                var i, nk;
                for(i = 0; i < sorted_u.length; i ++){
                    nk = d.channels[sorted_u[i]];
                    nk.item = mkItem(nk)
                    sortLayerUp.appendChild(nk.item);
                }
                for(i = 0; i < sorted_d.length; i ++){
                    nk = d.channels[sorted_d[i]];
                    nk.item = mkItem(nk)
                    sortLayerDown.appendChild(nk.item);
                }
                function mkItem(nk){
                    var e = mkdiv('apf-channel-sl-t');
                    e.innerHTML = nk.text;
                    e.apfKey = nk.key;
                    return e;
                }
                resort();
            }
            var s_x, s_y, origin_sort_u, origin_sort_d, from_up, moved;
            function s_u_s(e){
                if(e.target.className == 'apf-channel-sl-t'){
                    from_up = true;
                    s_g_s(e);
                    sortItemToDrag.style[tfAName] = 'translate('+sorting.apfX+'px,'+(sorting.apfY+config.SIZE.CHANNEL_HEIGHT_ALL)+'px)';
                    e.preventDefault();
                    e.stopPropagation();
                    return false;
                }
            }
            function s_d_s(e){
                if(e.target.className == 'apf-channel-sl-t'){
                    from_up = false;
                    s_g_s(e);
                    sortItemToDrag.style[tfAName] = 'translate('+sorting.apfX+'px,'+(sorting.apfY+h_sort_layer+config.SIZE.CHANNEL_SORT_LABEL_HEIGHT+config.SIZE.CHANNEL_HEIGHT_ALL)+'px)';
                    e.preventDefault();
                    e.stopPropagation();
                    return false;
                }
            }
            function s_g_s(e){
                sorting = e.target;
                sorting.className += ' dragging';
                window.addEventListener('touchmove', s_u_m);
                window.addEventListener('touchend',  s_u_e);
                s_x = sorting.apfX - e.touches[0].clientX;
                s_y = sorting.apfY - e.touches[0].clientY;
                sortItemToDrag.style.display = 'block';
                sortItemToDrag.innerHTML = e.target.innerHTML;
                origin_sort_d = sorted_d;
                origin_sort_u = sorted_u;
                moved = false;
            }
            var sort_cross = false;
            
            function s_u_m(e){
                var tx = e.touches[0].clientX + s_x;
                var ty = e.touches[0].clientY + s_y;
                var dy, nx, ny;
                var h1 = h_sort_layer + config.SIZE.CHANNEL_SORT_LABEL_HEIGHT;
                if(from_up){
                    if(ty > h_sort_layer){
                        sort_cross = true;
                        ny = Math.floor((ty - h1) / item_height);
                    }else{
                        sort_cross = false;
                        ny = Math.floor(ty / item_height);
                    }
                    dy = ty + config.SIZE.CHANNEL_HEIGHT_ALL;
                    
                }else{
                    if(ty < 0){
                        sort_cross = true;
                        ny = Math.floor((ty + h1) / item_height);
                    }else{
                        sort_cross = false;
                        ny = Math.floor(ty / item_height);
                    }
                    dy = ty + config.SIZE.CHANNEL_HEIGHT_ALL + h1;
                }
                nx = Math.floor(tx / item_width) + 1;
                
                var au_after = [];
                var ad_after = [];
                var i, m, it = true;
                sortItemToDrag.style[tfAName] = 'translate('+tx+'px,'+dy+'px)';
                sorted_u = [];
                sorted_d = [];
                if(ny < 0){
                    ny = 0;
                }
                for(i = 0; i < origin_sort_u.length; i ++){
                    m = d.channels[origin_sort_u[i]].item;
                    if(m.apfR < ny || (m.apfR == ny && m.apfC < nx)){
                        sorted_u.push(origin_sort_u[i]);
                    }else{
                        au_after.push(origin_sort_u[i]);
                    }
                }
                for(i = 0; i < origin_sort_d.length; i ++){
                    m = d.channels[origin_sort_d[i]].item;
                    if(m.apfR < ny || (m.apfR == ny && m.apfC < nx)){
                        sorted_d.push(origin_sort_d[i]);
                    }else{
                        ad_after.push(origin_sort_d[i]);
                    }
                }
                if(from_up){
                    if(sort_cross){
                        sorted_d.push('');
                    }else{
                        sorted_u.push('');
                    }
                }else{
                    if(sort_cross){
                        sorted_u.push('');
                    }else{
                        sorted_d.push('');
                    }
                }
                
                sorted_u = sorted_u.concat(au_after);
                sorted_d = sorted_d.concat(ad_after);
                resort();
                moved = true;
                e.preventDefault();
                e.stopPropagation();
                return false;
            }
            function s_u_e(e){
                sorting.className = 'apf-channel-sl-t';
                window.removeEventListener('touchmove', s_u_m);
                window.removeEventListener('touchend',  s_u_e);
                sortItemToDrag.style.display = 'none';
                if(!moved){
                    return;
                }
                var au = [];
                var ad = [];
                var i;
                if(sort_cross){
                    if(from_up){
                        sortLayerDown.appendChild(sorting);
                    }else{
                        sortLayerUp.appendChild(sorting);
                    }
                }
                for(i = 0; i < sorted_u.length; i ++){
                    if(sorted_u[i].length == 0){
                        au.push(sorting.apfKey);
                    }else if(sorting.apfKey == sorted_u[i]){
                        
                    }else{
                        au.push(sorted_u[i]);
                    }
                }
                for(i = 0; i < sorted_d.length; i ++){
                    if(sorted_d[i].length == 0){
                        ad.push(sorting.apfKey);
                    }else if(sorting.apfKey == sorted_d[i]){
                        
                    }else{
                        ad.push(sorted_d[i]);
                    }
                }
                sorted_u = au;
                sorted_d = ad;
                resort();
                sorting = null;
            }
            sortLayerUp.addEventListener('touchstart', s_u_s);
            sortLayerDown.addEventListener('touchstart', s_d_s);
            
            d.refreshChannel = function(c, y){
                c = c || d.apfChannel;
                d.apfLinkList && d.apfLinkList.apfClearContent();
                setTimeout(function(){
                    N('appf.channel', 
                        {
                            channel : c
                        }, 
                        function(data){
                            d.apfLinkList && d.apfLinkList.apfUpdateContent(data.args.list, y);
                            localData[c] = {
                                data   : data.args.list,
                                offset : 0
                            };
                        }, 
                        function(data){
                            console.log('Error:' + data);
                        }
                    );
                }, 100);
                
            }
            d.linkList = function(l){
                d.apfLinkList = l;
                l.apfLinkChannel = d;
            }
            d.apfLinkList = null;
        }
    };
    
    return Channel;
})